package com.xiaochong.tir.apiservice.scheduled;

import com.alibaba.fastjson.JSON;
import com.xc.logclient.utils.LogTrace;
import com.xiaochong.tir.apiservice.component.HbaseBaseQueryComponent;
import com.xiaochong.tir.apiservice.config.ExecutorConfig;
import com.xiaochong.service.common.config.redis.RedisServer;
import com.xiaochong.tir.apiservice.service.CmcDataDealService;
import com.xiaochong.tir.apiservice.service.CurrencyInfoService;
import com.xiaochong.tir.apiservice.service.KLineService;
import com.xiaochong.tir.common.data.hbasepo.KLineCmcData;
import com.xiaochong.tir.common.data.po.CurrencyInfo;
import com.xiaochong.tir.common.exception.hbase.HbaseCloseExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseConnectionExcetion;
import com.xiaochong.tir.common.exception.hbase.HbaseGetTableExcetion;
import com.xiaochong.tir.common.util.DateUtils;
import com.xiaochong.tir.common.util.HbaseTableUtils;
import com.xiaochong.tir.common.util.LogTraceKeysUtils;
import com.xiaochong.tir.common.util.RedisKeysUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.scheduling.annotation.Async;
import org.springframework.scheduling.annotation.EnableAsync;
import org.springframework.scheduling.annotation.EnableScheduling;
import org.springframework.scheduling.annotation.Scheduled;
import org.springframework.stereotype.Component;

import java.io.IOException;
import java.math.BigDecimal;
import java.time.LocalDateTime;
import java.util.List;
import java.util.Map;

/**
 * @Project : xc-tir
 * @Package Name : com.xiaochong.tir.apiservice.scheduled
 * @Description : TODO CMC 相关数据处理的定时任务
 * @Author : daizhiqing@xiaochong.com
 * @Creation Date : 2018年07月10日下午5:44
 * @ModificationHistory Who When What
 */
@Component
public class CmcScheduled {

    @Autowired
    private CmcDataDealService cmcDataDealService;

    @Autowired
    private CurrencyInfoService currencyInfoService;
    @Autowired
    private RedisServer redisServer;
    @Autowired
    private HbaseBaseQueryComponent hbaseBaseQueryComponent;


    @Async(ExecutorConfig.SCHEDULER_EXECUTOR_POOL)
    @Scheduled(cron = "0 1 0 * * ? ")
    public void dayKlineCmcScheduled(){
        LogTrace.beginTrace("Cmc数据日K线生成");
        LogTrace.info("Cmc数据日K线生成", LogTraceKeysUtils.DATA,"Cmc数据日K线生成dayKlineCmcScheduled");
        LocalDateTime dateDate = LocalDateTime.now();

        CurrencyInfo currencyInfo = new CurrencyInfo();
        currencyInfo.setEnableFlag(true);
        List<CurrencyInfo> currencyInfoList = currencyInfoService.selectByEntityList(currencyInfo);

        if (currencyInfoList != null && currencyInfoList.size() > 0) {
            LogTrace.info("initCmcKlineData","currencyInfoList" ,currencyInfoList.size()+"");

            for (CurrencyInfo currencyInfoBase : currencyInfoList) {
                try {
                    cmcDataDealService.cmcKDataDay(dateDate ,  currencyInfoBase.getCmcId());
                }catch (Exception e){
                    e.printStackTrace();
                    LogTrace.error("Cmc数据日K线生成失败"+currencyInfoBase.getCmcId() , e);
                }
            }
        }
        LogTrace.info("Cmc数据日K线生成", LogTraceKeysUtils.DATA, "Cmc数据日K线生成dayKlineCmcScheduled定时执行完成");
        LogTrace.endTrace();
    }


    @Async(ExecutorConfig.SCHEDULER_EXECUTOR_POOL)
//    @Scheduled(cron = "0 0 0/1 * * ? ")
    @Scheduled(fixedRate = 1000*60*60)
    public void calueCmcPriceHighLowScheduled(){
        LogTrace.beginTrace("Cmc数据计算最高价最低价");
        LogTrace.info("Cmc数据计算最高价最低价", LogTraceKeysUtils.DATA,"Cmc数据计算最高价最低价calueCmcPriceHighLowScheduled");
        LocalDateTime dateDate = LocalDateTime.now();

        CurrencyInfo currencyInfo = new CurrencyInfo();
        currencyInfo.setEnableFlag(true);
        List<CurrencyInfo> currencyInfoList = currencyInfoService.selectByEntityList(currencyInfo);
        if(currencyInfoList != null && currencyInfoList.size()>0){

            for (CurrencyInfo currencyInfoBase : currencyInfoList) {
                cmcDataDealService.calueCmcPriceHighLowScheduled(dateDate , currencyInfoBase.getCmcId());
            }
        }
        LogTrace.info("Cmc数据计算最高价最低价", LogTraceKeysUtils.DATA, "Cmc数据计算最高价最低价calueCmcPriceHighLowScheduled定时执行完成");
        LogTrace.endTrace();
    }

    @Async
    @Scheduled(cron="0 21 0 * * ?")
    public void cmcMaData() {
        LogTrace.beginTrace("计算CMC数据的Ma均线");

        LogTrace.info("计算CMC数据的Ma均线" , LogTraceKeysUtils.DATA ,"计算CMC数据的Ma均线定时任务启动");

        CurrencyInfo currencyInfo = new CurrencyInfo();
        currencyInfo.setEnableFlag(true);
        List<CurrencyInfo> currencyInfoList = currencyInfoService.selectByEntityList(currencyInfo);
        if(currencyInfoList != null && currencyInfoList.size()>0){
            for (CurrencyInfo currencyInfoBase : currencyInfoList) {
                String cmcId = currencyInfoBase.getCmcId();
                //计算某个货币的Ma7均线
                BigDecimal ma7 = cmcDataDealService.getCmcMaData(cmcId , 7);
                redisServer.set(RedisKeysUtils.CMC_DATA_MA_7+cmcId,ma7);
                //计算某个货币的Ma30均线
                BigDecimal ma30 = cmcDataDealService.getCmcMaData(cmcId , 30);
                redisServer.set(RedisKeysUtils.CMC_DATA_MA_30+cmcId,ma30);
                //计算某个货币的Ma60均线
                BigDecimal ma60 = cmcDataDealService.getCmcMaData(cmcId , 60);
                redisServer.set(RedisKeysUtils.CMC_DATA_MA_60+cmcId,ma60);

                //获取昨天的收盘价格计算
                LocalDateTime dateCalculate = LocalDateTime.now().minusDays(1);
                String rowKey = cmcId + DateUtils.localDateTimeFormatString( dateCalculate , DateUtils.format_ymds);
                try {
                    Map<String,Object> map = hbaseBaseQueryComponent.selectData(HbaseTableUtils.CURRENCY_INFO_K_LINE_TABLE_NAME ,rowKey);

                    if(map.size() <= 0 ){
                        continue;
                    }
                    //某一天日K线
                    KLineCmcData kLineCmcDay = JSON.parseObject(JSON.toJSONString(map), KLineCmcData.class);
                    String msgLast7 = "暂无解读";
                    String msgLast30 = "暂无解读";
                    if(kLineCmcDay != null){
                        //获取收盘价格
                        //TODO:进行比较获取趋势解读
                        BigDecimal close = new BigDecimal(kLineCmcDay.getClosePrice());


                        //收盘指数>=ma7、且收盘指数>=ma30，则：近7天大盘处于走强趋势中
                        if(close.compareTo(ma7)>=0 && close.compareTo(ma30)>=0){
                            msgLast7 = "近7天货币价格处于走强趋势中";
                        }
                        //收盘指数>=ma7、且收盘指数<ma30，则：近7天大盘反弹未突破
                        if(close.compareTo(ma7)>=0 && close.compareTo(ma30)<0){
                            msgLast7 = "近7天货币价格反弹未突破";
                        }
                        //收盘指数<ma7、且收盘指数>=ma30，则：近7天大盘下跌有支撑
                        if(close.compareTo(ma7)<0 && close.compareTo(ma30)>=0){
                            msgLast7 = "近7天货币价格下跌有支撑";
                        }
                        //收盘指数<ma7、且收盘指数<ma30，则：近7天大盘处于走弱趋势中
                        if(close.compareTo(ma7)<0 && close.compareTo(ma30)<0){
                            msgLast7 = "近7天货币价格处于走弱趋势中";
                        }


                        //若过去一天 收盘指数>=ma30、且收盘指数>=ma60，则：1个月大盘处于走强趋势中
                        if(close.compareTo(ma30)>=0 && close.compareTo(ma60)>=0){
                            msgLast30 = "1个月货币价格处于走强趋势中";
                        }
                        //若过去一天 收盘指数>=ma30、且收盘指数<ma60，或者过去一天 收盘指数<ma30、且收盘指数>=ma130，则：近1个月大盘处于盘整
                        if((close.compareTo(ma30)>=0 && close.compareTo(ma60)<0) || (close.compareTo(ma30)<0 && close.compareTo(ma60)>=0)){
                            msgLast30 = "近1个月货币价格处于盘整";
                        }
                        //若过去一天 收盘指数<ma30、且收盘指数<ma60，则：近1个月大盘处于走弱趋势中
                        if(close.compareTo(ma30)<0 && close.compareTo(ma60)<0){
                            msgLast30 = "近1个月货币价格处于走弱趋势中";
                        }

                        redisServer.set(RedisKeysUtils.CMC_DATA_7_STATUS+cmcId , msgLast7);
                        redisServer.set(RedisKeysUtils.CMC_DATA_30_STATUS+cmcId , msgLast30);
                    }
                } catch (HbaseConnectionExcetion hbaseConnectionExcetion) {
                    hbaseConnectionExcetion.printStackTrace();
                } catch (HbaseGetTableExcetion hbaseGetTableExcetion) {
                    hbaseGetTableExcetion.printStackTrace();
                } catch (IOException e) {
                    e.printStackTrace();
                } catch (HbaseCloseExcetion hbaseCloseExcetion) {
                    hbaseCloseExcetion.printStackTrace();
                }

            }
        }

        LogTrace.endTrace();
    }
}
